<template>
  <div class="v-model-tree">
    <div class="_tree-header">
      <div class="_left-operate">
        <span title="展开" @click="expandAll">
          <img src="statics\icons\app\iconspread.svg" alt="">
        </span>
        <span title="收缩" @click="collapseAll">
          <img src="statics\icons\app\iconshrink.svg" alt="">
        </span>
        <span title="收藏">
          <img src="statics\icons\app\iconstar.svg" alt="">
        </span>
        <span title="搜索" @click="showSearch = !showSearch">
          <img src="statics\icons\app\iconsearch.svg" alt="">
        </span>
        
      </div>
      <div class="_right-operate">
        <a-dropdown :trigger="['click']" placement="bottomLeft">
          <span title="设置" class="_setting">
            <img src="statics\icons\app\iconproperty2.png" alt="">
            <a-icon type="down" style="font-size: 8px; color: rgba(0,0,0,.85); padding-top: 3px"/>
          </span>
          <a-menu slot="overlay" :trigger="['click']" class="_setting-menu">
            <a-menu-item key="0" @click="handleExtraFile">
              <div class="image-box">
                <a-checkbox :checked="showExtraFile"></a-checkbox>
              </div>
              显示扩展文件
            </a-menu-item>
          </a-menu>
        </a-dropdown>
        
      </div>
      <!-- <a-button size="small" @click="handleBreakDisabled">break disable</a-button> -->
    </div>
    <div :class="{'_search-container': true, 'show-search': showSearch}">
      
      <a-select
        show-search
        placeholder="请输入元素名称"
        option-filter-prop="children"
        class="_search"
        size="small"
        :not-found-content="null"
        @change="handleSelectChange"
        @search="handleSelectSearch"
        @dropdownVisibleChange="handleSelectDropdownVisibleChange"
      >
        <a-icon slot="suffixIcon" type="search"/>
        <a-select-option
          v-for="(item,index) in selectOptions"
          :key="index"
          :value="item.id"
          :title="item.label"
          style="width:50%">
          {{item.label}}
          <div style="float: left; display:flex; height: 100%; align-items: center; margin-right: 5px; min-height: 22px"> 
            <img :src="item.icon" alt="" >
          </div>           
        </a-select-option>
      </a-select>
    </div>
    
    <m-tree :treeData="treeData" :showExtraFile="showExtraFile" class="_custom-tree" sortByName>
      <m-tree-node slot="default" slot-scope="{nodeData}" :graphNode="nodeData"/>
    </m-tree>
  </div>
</template>

<script>
import TreeNode from './TreeNode';
import { debounce } from 'lodash';
import {
  Comment,
  sysml,
  SysmlCommonStructureHelper,
  SysmlDependency,
  SysmlDiagramHelper,
  SysmlPackage,
  SysmlPackageHelper,
  SysMLUtilHelper,
  UMLDIHelper,
  StateMachineHelper, GraphHelper
} from 'src/api/sysml-imports';
import { treeForEach, findNodeByValue, getNodePath, isActDiagramElement, getNodeParent, isStmDiagramElement, getUniqueName, getImgPath } from 'src/util/common';
import { ModelTreeDataGenerator } from 'src/api/generator/model-tree-data-generator';
import { RelationShipGenerator } from 'src/api/generator/relationship-create-generator';
import { attributeDetail } from 'components/Attribute/modals/AttributeDetail';
import { selectValue } from 'components/Attribute/modals/SelectValue';
import { ContextMenu } from 'components/common/ContextMenu/index';
import treeUtil from './treeUtil';
import graphUtil from "pages/mxgraph/graphUtil";
import { GenericTableApi }  from 'src/api/shape/GenericTableApi';
import { modelApi } from "src/api/model/modelApi";
import { createError, errorCode } from 'src/constants/ErrorConfig';
import { chooseElement } from '../common/ChooseElement.vue';
import { actions } from 'src/pages/mxgraph/Actions';
import { graphHelper } from '@/api/GraphHelper';
import Tree from 'src/components/common/Tree/MTree';

export default {
  name: 'model-tree',
  components: {
    'm-tree-node': TreeNode,
    "m-tree": Tree

  },
  props: {

  },
  data() {
    return {
      attributeDetailVisible: false, //// 已经显示详情,此时不能再弹出新的详情弹窗
      inSelectValue: false, //// 处于弹窗选择状态，不能再弹出选择弹窗
      treeData: [],
      expandedKeys: [],
      selectQuery: '',
      events: {
        //// 'model-add': this.loadTreeData,
        //// 'model-update': this.loadTreeData,
        //// 'model-delete': this.loadTreeData,
        'project-switch': this.loadTreeData,
        //// 'model-tree-add-selectkeys': this.onSelect,

        //// 'esc': this.handleEsc,
        //// 'ctrl-c': this.handleCopy,
        //// 'ctrl-v': this.handlePaste,
        //// 'change-in-edit-node': this.handleChangeInEditNode
      },

      toPasteNode: [],
      selectOpen: false,

      inEditNodeId: undefined,
      selectOptions: [],
      showSearch: false,
      showExtraFile: false,
      fakeNode: null,
      callback: null

    };
  },
  computed: {

  },
  watch: {

  },
  mounted(){
    this.$bus.onBatch(this.events);
    this.loadTreeData();
    requestIdleCallback(this.workLoop);
  },
  beforeDestroy() {
    this.$bus.offBatch(this.events);

  },
  methods: {
    loadTreeData(option){
      const project = app.activeProject;
      if (!project) return console.error('cant not find project');
      this.initTree();
      app.sysmlModel.expand = true;
      //// app.sysmlModel.children = [];
      this.treeData = [app.sysmlModel];

    },
    initTree(){
      treeUtil.updateGraphNodeChildren(app.sysmlModel, true);
    },
    handleBreakDisabled(){
      console.log('click');
      treeForEach([app.sysmlModel], node => {
        //// console.log('dis');
        node.disabled = false;
      });
    },
    handleSelect(graphNode){
      if (graphNode === app.selectedElement) return;
      actions.getAction('selectOnTree').run(graphNode);

    },

    handleEsc(){
      this.toPasteNode = [];

    },

    handleSelectSearch: debounce(function(query){
      const flatData = [];
      if (!this.selectOpen || query === '' ) return flatData;
      query = query.toLowerCase();
      treeForEach(this.treeData, i => {
        const name = i.model && (i.model.name || i.model.body || i.title);
        if (name && name.toLowerCase().includes(query)) {
          const data = { label: i.title, id: i.id, icon: i.iconPath, placeholder: '' };
          if (name.toLowerCase() === query) {
            flatData.unshift(data);
          } else {
            flatData.push(data);
          }
        };
      });
      this.selectOptions = flatData;
      console.log('selectOptions', this.selectOptions);

    }, 200),
    handleSelectChange(id){
      console.log('handleSelectChange', id);

      const graphNode = id && graphHelper.getGraphNodeById(id, app.activeProjectId);
      if (graphNode) {
        this.handleSelect(graphNode);
      }

    },
    handleSelectDropdownVisibleChange(open){
      this.selectOpen = open;
    },

    handleExtraFile() {
      this.showExtraFile = !this.showExtraFile;
    },

    expandAll() {
      this.callback = node => node.expand = true;
      this.fakeNode = { children: this.treeData[0].children, node: this.treeData[0], parent: null, sibling: null, child: null };
      //// treeForEach(this.treeData, i => {
      ////   i.expand = true;
      //// });
    },

    collapseAll() {
      this.callback = node => node.expand = false;
      this.fakeNode = { children: this.treeData[0].children, node: this.treeData[0], parent: null, sibling: null, child: null };
      //// treeForEach(this.treeData, i => {
      ////   i.expand = false;
      //// });
    },

    //// 查找符合条件的node
    findNode(node) {
      console.log('node', node, this.treeData);
      const children = node.children;
      let currentChildren = null;
      for (let i = 0; i < children.length; i++) {
        const child = children[i];
        const childNode = { children: child.children, node: child, parent: node };
        if (i === 0) {
          node.child = childNode;
        } else if (currentChildren) {
          currentChildren.sibling = childNode;
        }
        currentChildren = childNode;
      }
    },

    //// 递归树节点
    searchTree(fakeNode, callback) {
      this.findNode(fakeNode);
      callback(fakeNode.node);
      if (fakeNode.child) {
        fakeNode = fakeNode.child;
      } else {
        while (fakeNode) {
          if (fakeNode.sibling) {
            fakeNode = fakeNode.sibling;
            break;
          } else {
            fakeNode = fakeNode.parent;
          }
        }
      }

      return fakeNode;
    },

    workLoop(deadline) {
      let shouldYield = false;
      while (this.fakeNode && !shouldYield) {
        this.fakeNode = this.searchTree(this.fakeNode, this.callback);
        shouldYield = deadline.timeRemaining() < 1;
      }     
      requestIdleCallback(this.workLoop);
    }

  }
};
</script>

<style lang='scss'>
//// diagramTree 也会用到此处样式
._setting-menu {
  .ant-dropdown-menu-item {
    .image-box {
      background-color: transparent;
      .ant-checkbox {
        &:hover {
          .ant-checkbox-inner {
            border-color: #3483B8;
          }
        }
      }
      .ant-checkbox-checked {
        .ant-checkbox-inner {
          background-color: #3483B8;
          border-color: #3483B8;
        }
      }
    }   
  }
}
.v-model-tree {
  height:100% ;
  display: flex;
  flex-direction: column;
  ._tree-header {
    background: #D4EBF8;
    border-bottom: 1px solid #B1CEE2;
    width: 100%;
    height: 29px;
    display: flex;
    justify-content: space-between;
    padding: 0 15px;
    .ant-select-open .ant-select-arrow-icon svg {
      transform: rotate(0);
    }
    ._left-operate, ._right-operate {
      display: flex;
      height: 100%;
      align-items: center;
      span {
        display: inline-block;
        width: 14px;
        height: 14px;
        line-height: 14px;
        font-size: 0;
        margin-right: 8px;
        cursor: pointer;
        img {
          vertical-align: middle;
          width: 14px;
        }
        &._setting {
          width: 26px;
          height: 20px;
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-right: 0;
        }
      }
    }
  }
  ._search-container {
    transition: height ease .3s;
    height: 0;
    overflow: hidden;
    padding: 0 9px;
    background: #f7f7f7;
    &.show-search {
      height: 33px;    
    }
  }
  ._search {
    width: 100%;
    height: 33px;
    border-bottom: 1px solid #e9e9e9;
    padding: 4px 0;
    
    .anticon-search {
      svg {
        transform: unset !important;
      }
    }
  }
  ._custom-tree {
    font-size: 12px;
    padding: 8px 8px;
    //// height: calc(100% - 34px);
    flex: 1;
    overflow: auto;
    //// li.ant-tree-treenode-disabled > .ant-tree-node-content-wrapper span {
    ////   cursor: pointer;
    //// }
    
  }
  ._operate-menu {
    height: 30px;
    background: #D4EBF8;
  }

}

.model-tree::-webkit-scrollbar-thumb {
  background-color: #d9d9d9;
}
</style>
